package api

import (
	"anban/logic"
	"anban/models"
	"anban/service"
	"anban/utils"
	"anban/utils/wechat"
	"fmt"
	"github.com/astaxie/beego"
	"net/url"
	"os"
	"strconv"
	"time"
)

type UserController struct {
	BaseController
}

//  检查用户是否登录
func (c *UserController) CheckLogin() {
	var res *utils.ResJsonStruct
	userId := c.GetSession("miniUserId")

	if userId == nil {
		res = utils.ResJson(1000, "请先登录", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	p := map[string]interface{}{}
	p["id"] = userId
	p["api"] = true
	user := service.GetUserInfo(p)

	if user.Id <= 0 {
		res = utils.ResJson(1000, "没有获取到用户信息", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	res = utils.ResJson(0, "已登陆", user)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 小程序登录
func (c *UserController) MiniProgramLogin() {
	var res *utils.ResJsonStruct
	/*code := c.GetString("code")

	if len(code) <= 0 {
		res = utils.ResJson(1010, "请提供code", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	miniLogin := wechat.NewMiniLogin(code)
	miniLoginRes, err := miniLogin.Login()
	if err != nil {
		res = utils.ResJson(1010, fmt.Sprintf("登录失败:%s", err.Error()), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	if miniLoginRes.Errcode != 0 {
		res = utils.ResJson(1010, fmt.Sprintf("登录失败:%s", miniLoginRes.Errmsg), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	if len(miniLoginRes.Unionid) <= 1 {
		res = utils.ResJson(1010, fmt.Sprintf("登录失败:无法获取unionid"), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	p := map[string]interface{}{}
	p["unionId"] = miniLoginRes.Unionid
	user := service.GetUserInfo(p)
	if user.Id <= 0 {
		res = utils.ResJson(1010, fmt.Sprintf("登录失败:请先关注安伴校园公众号"), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	var editInput url.Values

	editInput = url.Values{
		"id":           {fmt.Sprintf("%d", user.Id)},
		"mini_open_id": {miniLoginRes.Openid},
	}
	service.EditUser(editInput)*/

	p := map[string]interface{}{}
	p["id"] = 1
	user := service.GetUserInfo(p)

	c.SetSession("miniUserId", user.Id)
	sessionId := c.CruSession.SessionID()

	data := struct {
		SessionId string       `json:"session_id"`
		UserInfo  *models.User `json:"user_info"`
	}{
		SessionId: sessionId,
		UserInfo:  user,
	}

	res = utils.ResJson(0, "登录成功", data)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 获取签约支付信息
func (c *UserController) GetContractInfo() {
	var res *utils.ResJsonStruct
	var p map[string]interface{}
	var addInput url.Values
	userId := c.GetSession("miniUserId")
	ip := c.Ctx.Input.IP()

	p = map[string]interface{}{}
	p["id"] = userId
	user := service.GetUserInfo(p)

	contractCode := service.GetContractCode()
	addInput = url.Values{
		"user_id":       {fmt.Sprintf("%d", user.Id)},
		"contract_code": {contractCode},
	}
	miniProgramContractId, err := service.AddMiniProgramContract(addInput)
	if err != nil {
		res = utils.ResJson(1020, fmt.Sprintf("签约记录添加失败:%s", err.Error()), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	miniContract := wechat.NewMiniContract(miniProgramContractId, contractCode, user.RealName, ip, user.Phone, user.MiniOpenId, fmt.Sprintf("%d", user.Id))
	res = utils.ResJson(0, "成功获取签约信息", miniContract)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 家庭成员
func (c *UserController) FamilyMember() {
	var res *utils.ResJsonStruct

	userId := c.GetSession("miniUserId")
	p := map[string]interface{}{}
	p["id"] = userId
	user := service.GetUserInfo(p)

	p = map[string]interface{}{}
	p["familySn"] = user.FamilySn
	p["status"] = 1
	p["relation"] = true
	p["api"] = true
	_, memberList := service.GetUserList(p)

	res = utils.ResJson(0, "成功获取数据", memberList)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 家长通讯录
func (c *UserController) ParentBook() {
	var res *utils.ResJsonStruct

	count, _ := beego.AppConfig.Int("loadcount")
	curPage, _ := strconv.Atoi(c.GetString("p"))
	if curPage <= 0 {
		curPage = 1
	}

	userId := c.GetSession("miniUserId")
	p := map[string]interface{}{}
	p["id"] = userId
	user := service.GetUserInfo(p)

	var parentList []*models.User
	if len(user.FamilySn) > 0 {
		var classIds []int64
		p = map[string]interface{}{}
		p["familySn"] = user.FamilySn
		_, studentList := service.GetStudentList(p)
		for _, student := range studentList {
			classIds = append(classIds, student.Class.Id)
		}

		var studentIds []int64
		if len(classIds) > 0 {
			p = map[string]interface{}{}
			p["status"] = 1
			p["classIds"] = classIds
			_, classStudentList := service.GetStudentList(p)
			for _, classStudent := range classStudentList {
				studentIds = append(studentIds, classStudent.Id)
			}
		}

		if len(studentIds) > 0 {
			p = map[string]interface{}{}
			p["studentIds"] = studentIds
			p["relation"] = true
			p["api"] = true
			p["curPage"] = curPage
			p["perCount"] = count
			_, parentList = service.GetUserList(p)
		}
	}

	res = utils.ResJson(0, "成功获取数据", parentList)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 校园通讯录
func (c *UserController) TeacherBook() {
	var res *utils.ResJsonStruct

	userId := c.GetSession("miniUserId")
	p := map[string]interface{}{}
	p["id"] = userId
	user := service.GetUserInfo(p)

	p = map[string]interface{}{}
	p["status"] = 1
	p["api"] = true
	p["apiWithTeacher"] = true
	p["familySn"] = user.FamilySn
	_, studentList := service.GetStudentList(p)

	res = utils.ResJson(0, "成功获取数据", studentList)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 获取邀请二维码
func (c *UserController) InviteQrcode() {
	var res *utils.ResJsonStruct
	var name string
	page := "pages/index/index"
	domain := beego.AppConfig.String("domain")

	userId := c.GetSession("miniUserId")
	scene := fmt.Sprintf("invite_%d", userId)
	imgName := fmt.Sprintf("%s.jpg", scene)
	fullName := fmt.Sprintf("./static/qrcode/%s", imgName)

	if _, err := os.Stat(fullName); err != nil {
		name, err = wechat.CreateMiniSceneQrcode(scene, page, imgName, 500)
		if err != nil {
			res = utils.ResJson(1100, fmt.Sprintf("邀请二维码创建失败:%s", err.Error()), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	}

	resName := fmt.Sprintf("%s%s", domain, name)
	res = utils.ResJson(0, "成功获取数据", resName)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

func (c *UserController) Register() {
	var res *utils.ResJsonStruct
	input := c.Input()

	userId := c.GetSession("miniUserId")
	p := map[string]interface{}{}
	p["id"] = userId
	user := service.GetUserInfo(p)

	// 如果是老师，手机号和姓名已经有了，所以不需要
	if user.Identity == 0 {
		if len(input["mobile"][0]) <= 0 {
			res = utils.ResJson(1300, "请输入您的手机号", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		if !utils.IsMobile(input["mobile"][0]) {
			res = utils.ResJson(1300, "请输入正确的手机号", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		verifyRes, verifyMsg := service.DoCheckVerifyCode(input["mobile"][0], input["code"][0])
		if !verifyRes {
			res = utils.ResJson(1300, verifyMsg, "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		if len(input["realName"][0]) <= 0 {
			res = utils.ResJson(1300, "请输入您的姓名", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	}

	if len(input["studentName"][0]) <= 0 {
		res = utils.ResJson(1300, "请输入孩子的姓名", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	if len(input["studentIdcard"][0]) <= 0 {
		res = utils.ResJson(1300, "请输入孩子的身份证号", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	if len(input["relationId"][0]) <= 0 {
		res = utils.ResJson(1300, "请选择您与孩子的关系", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	p = map[string]interface{}{}
	p["realName"] = input["studentName"][0]
	p["idCard"] = input["studentIdcard"][0]
	student := service.GetStudentInfo(p)
	if student.Id <= 0 {
		res = utils.ResJson(1300, "请检查孩子的姓名和身份证号是否正确", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	if user.StudentRelation.Id > 0 {
		res = utils.ResJson(1300, "注册失败，您已经注册过了", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	var addInput url.Values
	var editInput url.Values

	familySn := student.FamilySn
	if len(familySn) <= 0 {
		familySn = user.FamilySn
		if len(familySn) <= 0 {
			familySn = service.GetUserFamilySn()
		}
		editInput = url.Values{
			"id": {fmt.Sprintf("%d", student.Id)},
			"family_sn": {familySn},
		}
		_, err := service.EditStudent(editInput)
		if err != nil {
			res = utils.ResJson(1300, "注册失败，请稍候重试", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		editInput = url.Values{
			"id": {fmt.Sprintf("%d", user.Id)},
			"is_main": {"1"},
			"student_relation_id": {input["relationId"][0]},
		}
	} else {
		if len(user.FamilySn) > 0 && user.FamilySn != familySn {
			res = utils.ResJson(1300, fmt.Sprintf("%s不是您的孩子", student.RealName), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		if len(user.FamilySn) > 0 && user.FamilySn == familySn {
			res = utils.ResJson(1300, "您已经注册过了，请不要重复操作", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		editInput = url.Values{
			"id": {fmt.Sprintf("%d", user.Id)},
			"is_main": {"0"},
			"student_relation_id": {input["relationId"][0]},
		}
	}
	editInput["family_sn"] = []string{familySn}

	if user.Identity == 2 {
		editInput["identity"] = []string{"3"}
	} else {
		editInput["identity"] = []string{"1"}
	}
	if _, ok := input["realName"]; ok {
		editInput["real_name"] = []string{input["realName"][0]}
	}
	if _, ok := input["mobile"]; ok {
		editInput["phone"] = []string{input["mobile"][0]}
	}
	_, err := service.EditUser(editInput)
	if err != nil {
		res = utils.ResJson(1300, "注册失败，请稍候重试", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	addInput = url.Values{
		"user_id": {fmt.Sprintf("%d", user.Id)},
		"student_id": {fmt.Sprintf("%d", student.Id)},
	}
	_, err = service.AddUserStudent(addInput)
	if err != nil {
		res = utils.ResJson(1300, "注册失败，请稍候重试", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	res = utils.ResJson(0, "注册成功", "")
	c.Data["json"] = res
	c.ServeJSON()
}

// 发送手机验证码
func (c *UserController) SendMobileMsg() {
	var res *utils.ResJsonStruct
	ip := c.Ctx.Input.IP()
	mobile := c.GetString("mobile")

	if len(mobile) <= 0 {
		res = utils.ResJson(1200, "请输入手机号", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	if !utils.IsMobile(mobile) {
		res = utils.ResJson(1200, "请输入正确的手机号", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	currentTime := time.Now().Unix()
	p := map[string]interface{}{}
	p["ip"] = ip
	ipVerifyCode := service.GetVerifyCodeInfo(p)
	if ipVerifyCode.Id > 0 {
		allowTime := ipVerifyCode.SendTime.Add(1 * time.Minute).Unix()
		if allowTime > currentTime { // 距离上次发送1分钟之内，不允许发送
			res = utils.ResJson(1200, "操作过于频繁，请稍候再进行操作", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	}

	code := utils.GenVerifyCode()
	p = map[string]interface{}{}
	p["key"] = mobile
	keyVerifyCode := service.GetVerifyCodeInfo(p)
	if keyVerifyCode.Id > 0 {
		allowTime := keyVerifyCode.SendTime.Add(1 * time.Minute).Unix()
		if allowTime > currentTime { // 距离上次发送1分钟之内，不允许发送
			res = utils.ResJson(1200, "操作过于频繁，请稍候再进行操作", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}

		sendMobileMsgRes := utils.SendMobileMessage([]string{mobile}, "523799", []string{code})
		if !sendMobileMsgRes {
			res = utils.ResJson(1200, "验证码发送失败，请稍后重试", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}

		count := keyVerifyCode.Count + 1
		editInput := url.Values{
			"id": {fmt.Sprintf("%d", keyVerifyCode.Id)},
			"ip": {ip},
			"code": {code},
			"count": {fmt.Sprintf("%d", count)},
		}
		_, err := service.EditVerifyCode(editInput)
		if err != nil {
			res = utils.ResJson(1200, "验证码发送失败，请稍后重试", "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}

		res = utils.ResJson(0, "验证码发送成功，请注意查收", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	sendMobileMsgRes := utils.SendMobileMessage([]string{mobile}, "523799", []string{code})
	if !sendMobileMsgRes {
		res = utils.ResJson(1200, "验证码发送失败，请稍后重试", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	addInput := url.Values{
		"ip": {ip},
		"key": {mobile},
		"code": {code},
		"count": {"1"},
	}
	_, err := service.AddVerifyCode(addInput)
	if err != nil {
		res = utils.ResJson(1200, "验证码发送失败，请稍后重试", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	res = utils.ResJson(0, "短信发送成功，请注意查收", "")
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 获取关系列表
func (c *UserController) Relations() {
	var res *utils.ResJsonStruct

	p := map[string]interface{}{}
	_, relationList := service.GetStudentRelationList(p)
	relationValues := service.GetStudentRelationListValues(relationList)

	res = utils.ResJson(0, "成功获取数据", relationValues)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 发布内容
func (c *UserController) Publish() {
	var res *utils.ResJsonStruct
	input := c.Input()

	if len(input["type_id"][0]) <= 0 {
		res = utils.ResJson(1300, "请选择通知类型", "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	userId := c.GetSession("miniUserId")
	input["user_id"] = []string{fmt.Sprintf("%d", userId)}

	if input["type_id"][0] == "1" { // 发布作业
		delete(input, "type_id")
		err := logic.AddHomework(input)
		if err != nil {
			res = utils.ResJson(1300, err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	} else if input["type_id"][0] == "2" { // 发布会议
		delete(input, "type_id")
		delete(input, "course_id")
		err := logic.AddMeeting(input)
		if err != nil {
			res = utils.ResJson(1300, err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	}

	res = utils.ResJson(0, "发布成功", "")
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 添加班级
func (c *UserController) AddClass() {
	var res *utils.ResJsonStruct
	input := c.Input()

	userId := c.GetSession("miniUserId")
	input["user_id"] = []string{fmt.Sprintf("%d", userId)}

	err := logic.AddClass(input)
	if err != nil {
		res = utils.ResJson(1300, err.Error(), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	res = utils.ResJson(0, "班级添加成功", "")
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 提现
func (c *UserController) Withdraw() {
	var res *utils.ResJsonStruct
	input := c.Input()

	userId := c.GetSession("miniUserId")
	input["user_id"] = []string{fmt.Sprintf("%d", userId)}

	err := logic.Withdraw(input)
	if err != nil {
		res = utils.ResJson(1300, err.Error(), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}

	res = utils.ResJson(0, "提现成功", "")
	c.Data["json"] = res
	c.ServeJSON()
}

// 提现记录
func (c *UserController) WithdrawList() {
	var res *utils.ResJsonStruct

	count, _ := beego.AppConfig.Int("loadcount")
	curPage, _ := strconv.Atoi(c.GetString("p"))
	if curPage <= 0 {
		curPage = 1
	}

	p := map[string]interface{}{}
	p["api"] = true
	p["userId"] = c.GetSession("miniUserId")
	p["curPage"] = curPage
	p["perCount"] = count
	_, withdrawList := service.GetWithdrawRecordList(p)

	res = utils.ResJson(0, "成功获取数据", withdrawList)
	c.Data["json"] = res
	c.ServeJSON()
	return
}

// 扣款记录
func (c *UserController) DeductionList() {
	var res *utils.ResJsonStruct

	count, _ := beego.AppConfig.Int("loadcount")
	curPage, _ := strconv.Atoi(c.GetString("p"))
	if curPage <= 0 {
		curPage = 1
	}

	p := map[string]interface{}{}
	p["api"] = true
	p["relation"] = true
	p["userId"] = c.GetSession("miniUserId")
	p["curPage"] = curPage
	p["perCount"] = count
	_, deductionList := service.GetDeductionRecordList(p)

	res = utils.ResJson(0, "成功获取数据", deductionList)
	c.Data["json"] = res
	c.ServeJSON()
	return
}
